import React from 'react';
import Live from './components/live'
import { View, StyleSheet, TouchableOpacity, Text, Alert, FlatList } from "react-native";
import { useEffect, useState, useCallback, useRef } from 'react';
import Adapt from './../../ulits/Adapt';
import io, { Socket } from 'socket.io-client';
import {
    RTCPeerConnection,
    RTCIceCandidate,
    RTCSessionDescription,
    mediaDevices,
    MediaStream,
    RTCView,
} from 'react-native-webrtc';
import AsyncStorage from '@react-native-async-storage/async-storage';


interface NavigationProps {
    navigation: {
        goBack: () => void;
        navigate: (screen: string, params?: any) => void;
    };
}

interface RTCPeerConnectionEventMap {
    icecandidate: RTCIceCandidateEvent;
    track: RTCTrackEvent;
}

interface RTCIceCandidateEvent {
    candidate: RTCIceCandidate | null;
}

interface RTCTrackEvent {
    streams: MediaStream[];
}

interface SignalingData {
    roomId: string;
    offer?: RTCSessionDescription;
    answer?: RTCSessionDescription;
    candidate?: RTCIceCandidate;
}

interface CommentData {
    senderId: string;
    message: string;
    timestamp: number;
}

const configuration = {
    iceServers: [
        { urls: 'stun:stun.l.google.com:19302' },
    ],
};

export default function App({ navigation }: NavigationProps) {
    const [open, setOpen] = useState(true);
    const [hasPermission, setHasPermission] = useState(false);
    const [isFrontCamera, setIsFrontCamera] = useState(false);
    const [cameraError, setCameraError] = useState<string | null>(null);
    const [roomId, setRoomId] = useState('');
    const [id, setId] = useState('');
    const [isStreaming, setIsStreaming] = useState(false);
    const [localStream, setLocalStream] = useState<MediaStream | null>(null);
    const [localSdp, setLocalSdp] = useState<RTCSessionDescription | null>(null); // To store the offer
    const [comments, setComments] = useState<CommentData[]>([]);
    const socketRef = useRef<Socket | null>(null);
    const peerConnectionRef = useRef<RTCPeerConnection | null>(null);
    const [frameRate, setFrameRate] = useState(30);
    const [currentBitrate, setCurrentBitrate] = useState<number | null>(null);

    
    const close = () => {
        // 发送结束直播事件到服务器
        if (socketRef.current && roomId && id) {
            socketRef.current.emit('end-live', { roomId, id });
            console.log('已发送结束直播事件到服务器');
        }

        // 清理本地资源
        if (localStream) {
            localStream.getTracks().forEach(track => track.stop());
        }
        if (peerConnectionRef.current) {
            peerConnectionRef.current.close();
        }
        if (socketRef.current) {
            socketRef.current.disconnect();
        }

        navigation.goBack();
    }

    const checkPermission = useCallback(async () => {
        try {
            const stream = await mediaDevices.getUserMedia({
                audio: true,
                video: {
                    width: { min: 640 },
                    height: { min: 480 },
                    frameRate: { min: frameRate, max: frameRate },
                    facingMode: isFrontCamera ? 'user' : 'environment',
                },
            });
            setLocalStream(stream);
            setHasPermission(true);
        } catch (error) {
            console.error('Permission check failed:', error);
            Alert.alert(
                '权限提示',
                '需要相机和麦克风权限才能开启直播',
                [{ text: '确定' }]
            );
        }
    }, [isFrontCamera, frameRate]);
    let g=async()=>{
        let a=JSON.parse(await AsyncStorage.getItem('user'))
        setRoomId(a.username)
        setId(a._id)
    }
    useEffect(() => {
        checkPermission();
        // 生成随机房间ID
        g()
    }, [checkPermission]);

    const toggleCamera = async () => {
        if (localStream) {
            localStream.getTracks().forEach(track => track.stop());
        }
        setIsFrontCamera(!isFrontCamera);
        try {
            const stream = await mediaDevices.getUserMedia({
                audio: true,
                video: {
                    width: { min: 640 },
                    height: { min: 480 },
                    frameRate: { min: frameRate, max: frameRate },
                    facingMode: !isFrontCamera ? 'user' : 'environment',
                },
            });
            setLocalStream(stream);
        } catch (error) {
            console.error('Camera switch failed:', error);
            Alert.alert('错误', '切换相机失败');
        }
    };

    const startLive = async () => {
        if (!localStream) {
            Alert.alert('错误', '无法获取相机流');
            return;
        }

        try {
            console.log('开始直播，本地流状态:', localStream.active);
            console.log('本地流轨道:', localStream.getTracks().map(track => ({
                kind: track.kind,
                enabled: track.enabled,
                muted: track.muted,
                readyState: track.readyState
            })));

            // 确保所有轨道都是启用的
            localStream.getTracks().forEach(track => {
                if (!track.enabled) {
                    console.log('启用轨道:', track.kind);
                    track.enabled = true;
                }
            });

            // 连接信令服务器
            socketRef.current = io('http://192.168.46.222:3020');
            console.log('已连接到信令服务器');

            // 创建PeerConnection
            peerConnectionRef.current = new RTCPeerConnection(configuration);
            console.log('创建PeerConnection成功');
            
            // 添加本地流到PeerConnection
            localStream.getTracks().forEach(track => {
                if (peerConnectionRef.current) {
                    console.log('添加轨道到PeerConnection:', track.kind);
                    peerConnectionRef.current.addTrack(track, localStream);
                }
            });

            // 验证轨道是否成功添加
            const senders = peerConnectionRef.current.getSenders();
            console.log('PeerConnection发送器:', senders.map(sender => ({
                track: sender.track?.kind,
                enabled: sender.track?.enabled
            })));

            // 处理ICE候选
            if (peerConnectionRef.current) {
                (peerConnectionRef.current as any).onicecandidate = (event: RTCIceCandidateEvent) => {
                    if (event.candidate && socketRef.current) {
                        console.log('发送ICE候选:', event.candidate);
                        socketRef.current.emit('ice-candidate', {
                            roomId,
                            candidate: event.candidate,
                        });
                    }
                };

                (peerConnectionRef.current as any).oniceconnectionstatechange = () => {
                    console.log('ICE连接状态:', peerConnectionRef.current?.iceConnectionState);
                };

                (peerConnectionRef.current as any).onconnectionstatechange = () => {
                    console.log('连接状态:', peerConnectionRef.current?.connectionState);
                };
            }

            // 创建并设置本地offer
            console.log('创建offer...');
            const offer = await peerConnectionRef.current.createOffer({
                offerToReceiveAudio: 1,
                offerToReceiveVideo: 1
            });
            console.log('offer创建成功:', offer);

            console.log('设置本地描述...');
            await peerConnectionRef.current.setLocalDescription(offer);
            setLocalSdp(offer); // 存储offer
            console.log('本地描述设置成功');

            // 创建房间
            socketRef.current.emit('create-room', roomId);
            console.log('创建房间:', roomId);

            // 发送offer到服务器进行存储和转发
            if (socketRef.current) {
                console.log('发送offer到服务器进行存储...');
                socketRef.current.emit('send-offer-to-server', {
                    id,
                    roomId,
                    offer: offer,
                });
                console.log('offer已发送到服务器');
            }
            
            // 处理answer
            socketRef.current.on('answer', async (data: SignalingData) => {
                console.log('收到answer:', data);
                if (peerConnectionRef.current && data.answer) {
                    try {
                        console.log('设置远程描述(answer)...');
                        await peerConnectionRef.current.setRemoteDescription(
                            new RTCSessionDescription(data.answer)
                        );
                        console.log('远程描述(answer)设置成功');
                    } catch (error) {
                        console.error('处理answer时出错:', error);
                    }
                }
            });

            // 处理ICE候选
            socketRef.current.on('ice-candidate', async (data: SignalingData) => {
                console.log('收到ICE候选:', data);
                if (peerConnectionRef.current && data.candidate) {
                    try {
                        console.log('添加ICE候选...');
                        await peerConnectionRef.current.addIceCandidate(
                            new RTCIceCandidate(data.candidate)
                        );
                        console.log('ICE候选添加成功');
                    } catch (error) {
                        console.error('添加ICE候选时出错:', error);
                    }
                }
            });

            // 处理评论
            socketRef.current.on('comment', (data: CommentData) => {
                console.log('收到评论:', data);
                setComments(prevComments => [...prevComments, data]);
            });

            setIsStreaming(true);
            setOpen(false);
        } catch (error) {
            console.error('启动直播失败:', error);
            Alert.alert('错误', '启动直播失败');
        }
    };

    // 自动调整帧率方法
    const changeFrameRate = async (newFps: number) => {
        if (frameRate === newFps) return;
        setFrameRate(newFps);
        if (localStream) {
            localStream.getTracks().forEach(track => track.stop());
        }
        try {
            const stream = await mediaDevices.getUserMedia({
                audio: true,
                video: {
                    width: { min: 640 },
                    height: { min: 480 },
                    frameRate: { min: newFps, max: newFps },
                    facingMode: isFrontCamera ? 'user' : 'environment',
                },
            });
            setLocalStream(stream);
            // 替换 PeerConnection 里的视频轨道
            if (peerConnectionRef.current) {
                const videoSender = peerConnectionRef.current.getSenders().find(s => s.track && s.track.kind === 'video');
                if (videoSender) {
                    videoSender.replaceTrack(stream.getVideoTracks()[0]);
                }
            }
        } catch (error) {
            console.error('自动调整帧率失败', error);
        }
    };

    useEffect(() => {
        let interval: NodeJS.Timeout;
        if (peerConnectionRef.current) {
            interval = setInterval(async () => {
                try {
                    const stats = await peerConnectionRef.current!.getStats();
                    let outboundVideo: any;
                    stats.forEach((report: any) => {
                        if (report.type === 'outbound-rtp' && report.kind === 'video') {
                            outboundVideo = report;
                        }
                    });
                    if (outboundVideo) {
                        const { packetsLost, packetsSent } = outboundVideo;
                        let lossRate = 0;
                        if (packetsSent && packetsLost) {
                            lossRate = packetsLost / (packetsSent + packetsLost);
                        }
                        if (lossRate > 0.05 && frameRate > 15) {
                            changeFrameRate(15);
                        } else if (lossRate < 0.01 && frameRate < 30) {
                            changeFrameRate(30);
                        }
                        // 统计码率
                        if (typeof outboundVideo.bitrateMean === 'number') {
                            setCurrentBitrate(Math.round(outboundVideo.bitrateMean / 1000)); // kbps
                        }
                    }
                } catch (e) {
                    // 忽略stats错误
                }
            }, 2000);
        }
        return () => {
            if (interval) clearInterval(interval);
        };
    }, [frameRate, peerConnectionRef.current]);

    if (!hasPermission) {
        return (
            <View style={styles.container}>
                <Text style={styles.errorText}>需要相机和麦克风权限</Text>
            </View>
        );
    }

    if (cameraError) {
        return (
            <View style={styles.container}>
                <Text style={styles.errorText}>相机错误: {cameraError}</Text>
            </View>
        );
    }

    return (
        <>
            {open ? (
                <Live 
                    onClose={close}
                    toggleCamera={toggleCamera}
                    isFrontCamera={isFrontCamera}
                    startLive={startLive}
                    device={null}
                    onError={setCameraError}
                    localStream={localStream}
                />
            ) : (
                <View style={styles.container}>
                    {localStream && (
                        <RTCView
                            streamURL={localStream.toURL()}
                            style={StyleSheet.absoluteFill}
                            objectFit="cover"
                        />
                    )}
                    {/* 房间号显示在左上角 */}
                    <View style={styles.topLeftContainer}>
                        <Text style={styles.roomIdText}>房间号: {roomId}</Text>
                        <Text style={styles.roomIdText}>
                            帧率: {frameRate}fps{currentBitrate !== null ? `  码率: ${currentBitrate}kbps` : ''}
                        </Text>
                    </View>

                    {/* 结束直播按钮在右上角 */}
                    <View style={styles.topRightContainer}>
                        <TouchableOpacity style={styles.stopButton} onPress={close}>
                            <Text style={styles.stopButtonText}>结束直播</Text>
                        </TouchableOpacity>
                    </View>

                    <View style={styles.commentsContainer}>
                        <FlatList
                            data={comments}
                            keyExtractor={(item, index) => index.toString()}
                            renderItem={({ item }) => (
                                <View style={styles.commentItem}>
                                    <Text style={styles.commentText}>
                                        {item.senderId.substring(0, 5)}: {item.message}
                                    </Text>
                                </View>
                            )}
                            contentContainerStyle={styles.commentsListContent}
                        />
                    </View>
                </View>
            )}
        </>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'black',
    },
    header: {
        position: 'absolute',
        top: Adapt.adapt(50),
        left: Adapt.adaptMargin(350),
        right: 0,
        zIndex: 2,
    },
    headerText: {
        color: 'white',
        fontSize: Adapt.adaptFontSize(22),
        fontWeight: 'bold',
    },
    controlsContainer: {
        position: 'absolute',
        bottom: Adapt.adapt(40),
        left: 0,
        right: 0,
        alignItems: 'center',
        zIndex: 2,
    },
    switchButton: {
        backgroundColor: 'rgba(0, 0, 0, 0.6)',
        paddingHorizontal: Adapt.adapt(20),
        paddingVertical: Adapt.adapt(10),
        borderRadius: Adapt.adaptRadius(20),
        marginBottom: Adapt.adapt(16),
    },
    switchButtonText: {
        color: 'white',
        fontSize: Adapt.adaptFontSize(16),
    },
    liveButton: {
        backgroundColor: '#FF3366',
        paddingHorizontal: Adapt.adapt(40),
        paddingVertical: Adapt.adapt(14),
        borderRadius: Adapt.adaptRadius(25),
    },
    liveButtonText: {
        color: 'white',
        fontSize: Adapt.adaptFontSize(18),
        fontWeight: 'bold',
    },
    errorText: {
        color: 'white',
        fontSize: Adapt.adaptFontSize(16),
        textAlign: 'center',
        marginTop: Adapt.adapt(20),
    },
    // New styles for positioning
    topLeftContainer: {
        position: 'absolute',
        top: Adapt.adapt(40),
        left: Adapt.adapt(20),
        zIndex: 10,
        backgroundColor: 'rgba(0,0,0,0.6)',
        paddingHorizontal: Adapt.adapt(15),
        paddingVertical: Adapt.adapt(8),
        borderRadius: Adapt.adaptRadius(10),
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.5,
        shadowRadius: 2,
        elevation: 5,
    },
    roomIdText: {
        color: 'white',
        fontSize: Adapt.adaptFontSize(15),
        fontWeight: 'bold',
    },
    topRightContainer: {
        position: 'absolute',
        top: Adapt.adapt(40),
        right: Adapt.adapt(20),
        zIndex: 10,
    },
    stopButton: {
        backgroundColor: '#FF3366',
        paddingHorizontal: Adapt.adapt(30),
        paddingVertical: Adapt.adapt(12),
        borderRadius: Adapt.adaptRadius(20),
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.8,
        shadowRadius: 2,
        elevation: 5,
    },
    stopButtonText: {
        color: 'white',
        fontSize: Adapt.adaptFontSize(16),
        fontWeight: 'bold',
    },
    commentsContainer: {
        position: 'absolute',
        bottom: Adapt.adapt(100), // Adjusted to be above the bottom controls if any, or just at a good position
        left: Adapt.adapt(10),
        right: Adapt.adapt(10),
        height: Adapt.adapt(250), // Height for the comments list
        maxHeight: Adapt.adapt(300),
        backgroundColor: 'rgba(0,0,0,0.5)',
        borderRadius: Adapt.adaptRadius(15),
        paddingVertical: Adapt.adapt(10),
        paddingHorizontal: Adapt.adapt(10),
        justifyContent: 'flex-end',
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 5 },
        shadowOpacity: 0.5,
        shadowRadius: 5,
        elevation: 8,
    },
    commentsListContent: {
        paddingBottom: Adapt.adapt(10),
        paddingTop: Adapt.adapt(10),
    },
    commentItem: {
        backgroundColor: 'rgba(255,255,255,0.15)',
        borderRadius: Adapt.adaptRadius(10),
        padding: Adapt.adapt(10),
        marginBottom: Adapt.adapt(8),
    },
    commentText: {
        color: 'white',
        fontSize: Adapt.adaptFontSize(14),
        lineHeight: Adapt.adaptFontSize(18),
    },
});